home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sound / 2151intf.c next >
C/C++ Source or Header  |  2000-05-23  |  6KB  |  324 lines

  1. /***************************************************************************
  2.  
  3.   2151intf.c
  4.  
  5.   Support interface YM2151(OPM)
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "fm.h"
  11. #include "ym2151.h"
  12.  
  13.  
  14. /* for stream system */
  15. static int stream[MAX_2151];
  16.  
  17. static const struct YM2151interface *intf;
  18.  
  19. static int FMMode;
  20. #define CHIP_YM2151_DAC 4    /* use Tatsuyuki's FM.C */
  21. #define CHIP_YM2151_ALT 5    /* use Jarek's YM2151.C */
  22.  
  23.  
  24. #if (HAS_YM2151)
  25.  
  26. #define YM2151_NUMBUF 2
  27.  
  28. static void *Timer[MAX_2151][2];
  29.  
  30. /* IRQ Handler */
  31. static void IRQHandler(int n,int irq)
  32. {
  33.     if(intf->irqhandler[n]) intf->irqhandler[n](irq);
  34. }
  35.  
  36. static void timer_callback_2151(int param)
  37. {
  38.     int n=param&0x7f;
  39.     int c=param>>7;
  40.  
  41.     Timer[n][c] = 0;
  42.     YM2151TimerOver(n,c);
  43. }
  44.  
  45. /* TimerHandler from fm.c */
  46. static void TimerHandler(int n,int c,int count,double stepTime)
  47. {
  48.     if( count == 0 )
  49.     {    /* Reset FM Timer */
  50.         if( Timer[n][c] )
  51.         {
  52.              timer_remove (Timer[n][c]);
  53.             Timer[n][c] = 0;
  54.         }
  55.     }
  56.     else
  57.     {    /* Start FM Timer */
  58.         double timeSec = (double)count * stepTime;
  59.  
  60.         if( Timer[n][c] == 0 )
  61.         {
  62.             Timer[n][c] = timer_set (timeSec, (c<<7)|n, timer_callback_2151 );
  63.         }
  64.     }
  65. }
  66.  
  67. #endif
  68.  
  69. /* update request from fm.c */
  70. void YM2151UpdateRequest(int chip)
  71. {
  72.     stream_update(stream[chip],0);
  73. }
  74.  
  75. static int my_YM2151_sh_start(const struct MachineSound *msound,int mode)
  76. {
  77.     int i,j;
  78.     int rate = Machine->sample_rate;
  79.     char buf[YM2151_NUMBUF][40];
  80.     const char *name[YM2151_NUMBUF];
  81.     int mixed_vol,vol[YM2151_NUMBUF];
  82.  
  83.     if( rate == 0 ) rate = 1000;    /* kludge to prevent nasty crashes */
  84.  
  85.     intf = msound->sound_interface;
  86.  
  87.     if( mode ) FMMode = CHIP_YM2151_ALT;
  88.     else       FMMode = CHIP_YM2151_DAC;
  89.  
  90.     switch(FMMode)
  91.     {
  92. #if (HAS_YM2151)
  93.     case CHIP_YM2151_DAC:    /* Tatsuyuki's */
  94.         /* stream system initialize */
  95.         for (i = 0;i < intf->num;i++)
  96.         {
  97.             mixed_vol = intf->volume[i];
  98.             /* stream setup */
  99.             for (j = 0 ; j < YM2151_NUMBUF ; j++)
  100.             {
  101.                 name[j]=buf[j];
  102.                 vol[j] = mixed_vol & 0xffff;
  103.                 mixed_vol>>=16;
  104.                 sprintf(buf[j],"%s #%d Ch%d",sound_name(msound),i,j+1);
  105.             }
  106.             stream[i] = stream_init_multi(YM2151_NUMBUF,
  107.                 name,vol,rate,i,OPMUpdateOne);
  108.         }
  109.         /* Set Timer handler */
  110.         for (i = 0; i < intf->num; i++)
  111.             Timer[i][0] =Timer[i][1] = 0;
  112.         if (OPMInit(intf->num,intf->baseclock,Machine->sample_rate,TimerHandler,IRQHandler) == 0)
  113.         {
  114.             /* set port handler */
  115.             for (i = 0; i < intf->num; i++)
  116.                 OPMSetPortHander(i,intf->portwritehandler[i]);
  117.             return 0;
  118.         }
  119.         /* error */
  120.         return 1;
  121. #endif
  122. #if (HAS_YM2151_ALT)
  123.     case CHIP_YM2151_ALT:    /* Jarek's */
  124.         /* stream system initialize */
  125.         for (i = 0;i < intf->num;i++)
  126.         {
  127.             /* stream setup */
  128.             mixed_vol = intf->volume[i];
  129.             for (j = 0 ; j < YM2151_NUMBUF ; j++)
  130.             {
  131.                 name[j]=buf[j];
  132.                 vol[j] = mixed_vol & 0xffff;
  133.                 mixed_vol>>=16;
  134.                 sprintf(buf[j],"%s #%d Ch%d",sound_name(msound),i,j+1);
  135.             }
  136.             stream[i] = stream_init_multi(YM2151_NUMBUF,
  137.                 name,vol,rate,i,YM2151UpdateOne);
  138.         }
  139.         if (YM2151Init(intf->num,intf->baseclock,Machine->sample_rate) == 0)
  140.         {
  141.             for (i = 0; i < intf->num; i++)
  142.             {
  143.                 YM2151SetIrqHandler(i,intf->irqhandler[i]);
  144.                 YM2151SetPortWriteHandler(i,intf->portwritehandler[i]);
  145.             }
  146.             return 0;
  147.         }
  148.         return 1;
  149. #endif
  150.     }
  151.     return 1;
  152. }
  153.  
  154. #if (HAS_YM2151)
  155. int YM2151_sh_start(const struct MachineSound *msound)
  156. {
  157.     return my_YM2151_sh_start(msound,0);
  158. }
  159. #endif
  160. #if (HAS_YM2151_ALT)
  161. int YM2151_sh_start(const struct MachineSound *msound)
  162. {
  163.     return my_YM2151_sh_start(msound,1);
  164. }
  165. #endif
  166.  
  167. void YM2151_sh_stop(void)
  168. {
  169.     switch(FMMode)
  170.     {
  171. #if (HAS_YM2151)
  172.     case CHIP_YM2151_DAC:
  173.         OPMShutdown();
  174.         break;
  175. #endif
  176. #if (HAS_YM2151_ALT)
  177.     case CHIP_YM2151_ALT:
  178.         YM2151Shutdown();
  179.         break;
  180. #endif
  181.     }
  182. }
  183.  
  184. void YM2151_sh_reset(void)
  185. {
  186.     int i;
  187.  
  188.     for (i = 0;i < intf->num;i++)
  189.     switch(FMMode)
  190.     {
  191. #if (HAS_YM2151)
  192.     case CHIP_YM2151_DAC:
  193.         OPMResetChip(i);
  194.         break;
  195. #endif
  196. #if (HAS_YM2151_ALT)
  197.     case CHIP_YM2151_ALT:
  198.         YM2151ResetChip(i);
  199.         break;
  200. #endif
  201.     }
  202.  
  203. }
  204.  
  205. static int lastreg0,lastreg1,lastreg2;
  206.  
  207. READ_HANDLER( YM2151_status_port_0_r )
  208. {
  209.     switch(FMMode)
  210.     {
  211. #if (HAS_YM2151)
  212.     case CHIP_YM2151_DAC:
  213.         return YM2151Read(0,1);
  214. #endif
  215. #if (HAS_YM2151_ALT)
  216.     case CHIP_YM2151_ALT:
  217.         return YM2151ReadStatus(0);
  218. #endif
  219.     }
  220.     return 0;
  221. }
  222.  
  223. READ_HANDLER( YM2151_status_port_1_r )
  224. {
  225.     switch(FMMode)
  226.     {
  227. #if (HAS_YM2151)
  228.     case CHIP_YM2151_DAC:
  229.         return YM2151Read(1,1);
  230. #endif
  231. #if (HAS_YM2151_ALT)
  232.     case CHIP_YM2151_ALT:
  233.         return YM2151ReadStatus(1);
  234. #endif
  235.     }
  236.     return 0;
  237. }
  238.  
  239. READ_HANDLER( YM2151_status_port_2_r )
  240. {
  241.     switch(FMMode)
  242.     {
  243. #if (HAS_YM2151)
  244.     case CHIP_YM2151_DAC:
  245.         return YM2151Read(2,1);
  246. #endif
  247. #if (HAS_YM2151_ALT)
  248.     case CHIP_YM2151_ALT:
  249.         return YM2151ReadStatus(2);
  250. #endif
  251.     }
  252.     return 0;
  253. }
  254.  
  255. WRITE_HANDLER( YM2151_register_port_0_w )
  256. {
  257.     lastreg0 = data;
  258. }
  259. WRITE_HANDLER( YM2151_register_port_1_w )
  260. {
  261.     lastreg1 = data;
  262. }
  263. WRITE_HANDLER( YM2151_register_port_2_w )
  264. {
  265.     lastreg2 = data;
  266. }
  267.  
  268. WRITE_HANDLER( YM2151_data_port_0_w )
  269. {
  270.     switch(FMMode)
  271.     {
  272. #if (HAS_YM2151)
  273.     case CHIP_YM2151_DAC:
  274.         YM2151Write(0,0,lastreg0);
  275.         YM2151Write(0,1,data);
  276.         break;
  277. #endif
  278. #if (HAS_YM2151_ALT)
  279.     case CHIP_YM2151_ALT:
  280.         YM2151UpdateRequest(0);
  281.         YM2151WriteReg(0,lastreg0,data);
  282.         break;
  283. #endif
  284.     }
  285. }
  286.  
  287. WRITE_HANDLER( YM2151_data_port_1_w )
  288. {
  289.     switch(FMMode)
  290.     {
  291. #if (HAS_YM2151)
  292.     case CHIP_YM2151_DAC:
  293.         YM2151Write(1,0,lastreg1);
  294.         YM2151Write(1,1,data);
  295.         break;
  296. #endif
  297. #if (HAS_YM2151_ALT)
  298.     case CHIP_YM2151_ALT:
  299.         YM2151UpdateRequest(1);
  300.         YM2151WriteReg(1,lastreg1,data);
  301.         break;
  302. #endif
  303.     }
  304. }
  305.  
  306. WRITE_HANDLER( YM2151_data_port_2_w )
  307. {
  308.     switch(FMMode)
  309.     {
  310. #if (HAS_YM2151)
  311.     case CHIP_YM2151_DAC:
  312.         YM2151Write(2,0,lastreg2);
  313.         YM2151Write(2,1,data);
  314.         break;
  315. #endif
  316. #if (HAS_YM2151_ALT)
  317.     case CHIP_YM2151_ALT:
  318.         YM2151UpdateRequest(2);
  319.         YM2151WriteReg(2,lastreg2,data);
  320.         break;
  321. #endif
  322.     }
  323. }
  324.